<?php

namespace control;
//管理员后台 - 文件共享
class shareClass extends adIndexClass
{
    private const page = 'share'; # 权限
    private const table = 'share'; # 数据表
    private const title = '文件共享';

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'name' => [
                        'name'  => '名称',
                        'width' => 400,
                        'sort'  => 1,
                    ],
                    'size' => [
                        'name'  => "大小",
                        'width' => 200,
                        'sort'  => 1,
                    ],
                    'time' => [
                        'name'  => "创建时间",
                        'width' => 300,
                        'sort'  => 1,
                    ],
                    'stid' => [
                        'name'  => '编辑人',
                        'width' => 300,
                    ],
                    'opt'  => [
                        'name'  => '操作',
                        'width' => 300,
                    ]
                ];
        }
        return $tr;
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true, $data = [])
    {
        $fileId = isset($data['fileId']) && $data['fileId'] ? $data['fileId'] : $this->post('fileId');
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "文件名" => text(["name" => "name", "title" => "文件名"]) .
                        hidden(["name" => "pid", 'value' => $this->get('pid') ?? 1]) .
                        hidden(["name" => "fileId", 'value' => $fileId])
                    ,
                ]
            ]
        ], 1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /*成本表列表-查询条件*/
    public function home()
    {
        $fileId = self::getId();
        $pid    = $this->get('pid') ?? 1;
        $html   = $this->homeOptions(false, ['fileId' => $fileId]);
        //控件
        $button = '';
        if ($this->power(self::page, "edit")) {
            $button .= "<span class='spanButton li-btn-blue-bg' onclick=\"document.{$fileId}form.img.click()\">上传文件</span>\n";
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'editPage', {'id': '" . self::getNo() . "', 'pid': '$pid' })\">新建文件夹</span>\n";
        }
        $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">删除</span>\n";
        if ($this->power(self::page, "edit")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'move'})\">移动</span>\n";
        }
        if ($this->power(self::page, "zip")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'zip','pid': '$pid'})\">压缩</span>\n";
        }
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button, searchOption: "{fileId:'$fileId'}"));
    }

    /*成本表列表-查询结果*/
    public function homeSearch()
    {
        $pid   = $this->post('pid');
        $where = " (`viewScope` LIKE '%" . self::$stid . "%' OR stid = '" . self::$stid . "') ";
        $like  = [
            'name' => $this->post('name'),
        ];
        $where .= search(["like" => $like]);
        // 判断是否是搜索
        $where .= $like['name'] ? '' : " AND `pid` = '$pid' ";

        //排序
        $orderBy = $this->listSort(array(
            "search" => $this->post('list_sort_key') ?: 'type DESC, time',
            "sort"   => $this->post('list_sort') ?: "desc",
            "array"  => array(),
        ));
        //获取查询结果
        $page = $this->page([
            "table" => self::table,
            "where" => $where,
            "order" => $orderBy['orderBy'],
        ]);
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "id")
        );
        //获取记录
        $url = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail";
        foreach ($page['array'] as $array) {
            $dominate = [
                "box" => [
                    "name"  => "id",
                    "value" => $array['id']
                ]
            ];
            $opt      = '';
            $ico      = "<img src='{$this->root}img/svg/file_share.svg' class='right'>";
            $name     = $array['name'];
            if ($array['type'] == 'folder') {
                // 图标
                $ico = "<img src='{$this->root}/img/svg/folder_share.svg' class='right'>";
                // 操作
                if ($this->power(self::page, "edit") || self::$stid == $array['stid']) {
                    $opt .= "<span class='spanA' onclick=\"layer('{$this->get('cla')}', 'editPage', {'id': '{$array['id']}', 'pid': '{$array['pid']}' })\">编辑</span>\n";
                }
                $name = "<a class='hover' onclick=\"refreshNowIframe('{$this->root}control/adIndex.html?cla={$this->get('cla')}&fun=home&pid={$array['id']}')\">{$name}</a>";
            } else {
                if ($this->power(self::page, "power") || self::$stid == $array['stid']) {
                    $opt .= "<span class='spanA' onclick=\"layer('{$this->get('cla')}', 'operate', {'id': '{$array['id']}', 'act': 'range' })\">权限</span>\n";
                }
                //下载权限判断
                $downloadScope = $array['downloadScope'] ? json_decode($array['downloadScope'], true) : [];
                if (in_array(self::$stid, (array)$downloadScope) || self::$stid == $array['stid']) {
                    $opt .= "<a class='spanA' target='_blank' href='" . root . $array['path'] . "' download='" . $array['name'] . "' title='" . $array['name'] . "'>下载</a>\n";
                }
                // 预览
                if (in_array($array['suffix'], ['jpg', 'png', 'gif', 'jpeg'])) {
                    $opt .= "<a class='spanA' target='_blank' href='" . root . $array['path'] . "' title='" . $array['name'] . "'>预览</a>\n";
                } elseif (in_array($array['suffix'], ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf'])) {
                    $array['format'] = $array['suffix'];
                    $url             = $this->wps($array);
                    $opt             .= "\n<a class='spanA' target='_blank' href='" . $url . "' title='" . $array['name'] . "'>预览</a>";
                }
            }
            $liButton[] = $this->dominate($dominate) . $ico;
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case "name":
                        $row[] = $name;
                        break;
                    case "size":
                        $row[] = self::formatSize($array['size']);
                        break;
                    case "stid":
                        $row[] = self::findStaff($array['stid']);
                        break;
                    case "opt":
                        $row[] = $opt;
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //控件
        $fileId = $this->post('fileId');
        $nav    = '<div class="share-nav">' . self::getNavHtml($pid) . '</div>';
        //生成页面
        $li = $this->li(array(
            "body"        => $body,
            "install"     => $installSearch,
            "button"      => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page"        => $page['para'],
        ));
        //返回
        $json['html'] =
            $nav .
            $page['hint'] .
            "<form name='listForm' class='share-container'>" .
            $li .
            "</form>" .
            $page['button'] .
            clear .
            $this->uploadHtml($pid, $fileId, $this->root . 'control/adIndex.html?cla=share&fun=chunkUpload') .
            $this->dragUploadHtml($pid, $this->root . 'control/adIndex.html?cla=share&fun=chunkUpload', 'body');
        return json_encode($json, 320);
    }

    /*文件上传检查-异步处理*/
    public function checkUpload()
    {
        $fileInfo  = json_decode($_POST['fileInfo'], true);
        $limitType = explode(',', para('fileFormat'));
        foreach ((array)$fileInfo as $key => $val) {
            $suffix = self::getExtension($val['name']);
            if (!empty($limitType) && !in_array($suffix, $limitType)) {
                $fileInfo[$key]['error'] = '文件不在上传类型范围中';
            }
        }
        if (empty($fileInfo)) {
            $json['warn'] = "未找到需要上传的文件";
        } else {
            foreach ((array)$fileInfo as $k => $array) {
                $upload_progress = query("upload_progress", " code = '" . $array['code'] . "' and target_id = '" . $array['target_id'] . "' and target = '" . $array['target'] . "' and stid = '" . self::$stid . "' and state = 0 ");
                if ($upload_progress['id']) {
                    static::update([
                        "table" => 'upload_progress',
                        "field" => [
                            'state'      => $array['error'] ? 2 : $array['state'],
                            'text'       => $array['error'],
                            'updateTime' => $this->time,
                        ],
                        "where" => " id = '" . $upload_progress['id'] . "' "
                    ]);
                    $fileInfo[$k]['id']     = $upload_progress['id'];
                    $fileInfo[$k]['chunk']  = $upload_progress['chunk'];
                    $fileInfo[$k]['chunks'] = $upload_progress['chunks'];
                } else {
                    $field = [
                        'id'         => self::getId(),
                        'code'       => $array['code'],
                        'target'     => $array['target'],
                        'name'       => $array['name'],
                        'size'       => $array['size'],
                        'target_id'  => $array['target_id'],
                        'chunks'     => $array['chunks'],
                        'state'      => $array['error'] ? 2 : 0,
                        'text'       => $array['error'],
                        'stid'       => self::$stid,
                        'updateTime' => date("Y-m-d H:i:s"),
                        'time'       => date("Y-m-d H:i:s"),
                    ];
                    static::insert([
                        'table' => 'upload_progress',
                        'field' => $field
                    ]);
                    $fileInfo[$k]['id']     = $field['id'];
                    $fileInfo[$k]['chunk']  = 0;
                    $fileInfo[$k]['chunks'] = $field['chunks'];
                }
            }
            $json['data'] = $fileInfo;
            $json['warn'] = 2;
        }
        resp:
        return json_encode($json, 320);
    }

    /*上传进度列表*/
    public function uploadList()
    {
        //数据库查询
        $fileInfo = $this->post('fileInfo');
        $data     = [];
        $task     = 0;
        foreach ((array)$fileInfo as $array) {
            $progress         = round($array['chunk'] / $array['chunks'] * 100, 2);
            $size             = round($array['size'] / 1024 / 1024, 2);
            $span             = "<span onclick=\"uploadAborted(this,'" . $array['id'] . "')\" class='upload-aborted {$array['id']}-close'>" . listDel . "</span>";
            $upload_file_name = "<div class='upload-file-name'>{$array['name']}</div>";
            if ($array['error']) {
                $schedule = "<div class='schedule-text red upload-error' title='{$array['error']}'>{$array['error']}</div>";
            } else {
                $task++;
                $schedule = "<div class='{$array['id']}-scale schedule-text'>{$progress}%</div>";
            }
            $data[] = [
                $span,
                "<div class='wrapper'>
                    <div id='{$array['id']}' class='first progress-bar active progress-bar-striped' style='width: {$progress}%'></div>
                    <div class='upload-aborted-text'>{$upload_file_name}<div class='upload-size'>{$size}M</div>{$schedule}</div>
                </div>"
            ];
        }
        $incomplete = '上传已完成，成功0个，失败'.count($fileInfo).'个。';
        $completedClass = '';
        //判断
        if ($task > 0) {
            $completedClass  = "style='display:none;'";
            $incomplete = "文件上传中，请稍后。。。";
        }
        $noData = "
            <div class='no-data-div hide'>
                <img class='no-data-img' src='{$this->root}img/svg/noData.svg' >
                <span class='no-data-text'>暂无数据</span>
            </div>
        ";
        //生成表单
        $html = "<div class='upload-zone'>
                    <div  class='upload-progress-zone' style='height: 320px;'>" . $this->tableShow([$data]) . $noData ."</div>
                    <div class='upload-zone-bottom winFoot'>
                        <span class='progress-incomplete'>{$incomplete}</span>
                        <input onclick=\"$('#shareUploadList').hide()\" type='button' class='progress-completed button' value='关闭'>
                    </div>
                </div>";
        //返回弹出层
        return $this->layer(array(
            "title" => '文件上传',
            "height" => 400,
            "width" => 616,
            "html" => $html,
            "zindex" => 100,
            "notClose" => $this->post('notClose'),
            "button" => false
        ));
    }

    /**
     * 上传附件
     */
    public function chunkUpload()
    {
        $file            = $_FILES['file'] ?? [];
        $info            = json_decode($_POST['info'], true);
        $state           = 0;
        $json            = [];
        $limitType       = explode(',', para('fileFormat'));
        $suffix          = self::getExtension($this->post('name'));
        $upload_progress = query("upload_progress", " id = '" . $info['id'] . "' ");
        if (empty($info)) {
            $json['warn'] = '未找到上传的数据';
        } elseif (empty($upload_progress['id'])) {
            $json['warn'] = 1;
        } elseif (!empty($limitType) && !in_array($suffix, $limitType)) {
            $json['warn'] = '你上传的文件不在上传类型范围中';
        } elseif (!$this->power($info['power'], 'edit')) {
            $json['warn'] = '你还没有编辑权限';
        } else {
            $result = $this->saveFileTemp($file, $info['id'] . '_' . $this->post('chunk'));
            if (!$result['code']) {
                $json['warn'] = $result['warn'];
            } else {
                //判断分片是否全部上传完成
                $uploadStatus = true;
                for ($i = 1; $i <= $this->post('chunks'); $i++) {
                    if (!file_exists(serverRoot . 'file/temp/' . $info['id'] . "_" . $i)) {
                        $uploadStatus = false;
                        break;
                    }
                }
                if (!$uploadStatus) {
                    $progress = round($this->post('chunk') / $this->post('chunks') * 100, 2);
                } else {
                    //合并分片
                    $url = 'file/share/' . date("Ym");
                    $this->_mkdir($url);
                    $fileName = suiji() . '.' . $suffix;
                    $fp       = fopen(serverRoot . $url . '/' . $fileName, "w");
                    for ($i = 1; $i <= $this->post('chunks'); $i++) {
                        $chunkName = serverRoot . 'file/temp/' . $info['id'] . "_" . $i;
                        $chunkData = file_get_contents($chunkName);
                        fwrite($fp, $chunkData);
                        @unlink($chunkName); //删除分片文件
                    }
                    fclose($fp);
                    $id = self::getNo();
                    //插入共享文件
                    $pInfo                     = query(self::table, " id = '$info[target_id]' ");
                    $field['path']             = $url . '/' . $fileName;
                    $field['name']             = $this->post('name');
                    $field['size']             = $this->post('size');
                    $field['viewScope']        = $pInfo['viewScope'];
                    $field['viewSelector']     = $pInfo['viewSelector'];
                    $field['delScope']         = $pInfo['delScope'];
                    $field['delSelector']      = $pInfo['delSelector'];
                    $field['downloadScope']    = $pInfo['downloadScope'];
                    $field['downloadSelector'] = $pInfo['downloadSelector'];
                    $field                     = array_merge($field, [
                        'id'     => $id,
                        'pid'    => $info['target_id'],
                        'type'   => 'file',
                        'stid'   => self::$stid,
                        'suffix' => $suffix,
                        'time'   => date("Y-m-d H:i:s"),
                    ]);
                    $json['warn']              = insert([
                        'table' => self::table,
                        'field' => $field
                    ]);
                    if ($json['warn'] == "新增成功") {
                        $state    = 1;
                        $progress = 100;
                    } else {
                        goto resp;
                    }
                }
                $json['warn'] = static::update([
                    "table" => 'upload_progress',
                    "field" => ['chunk' => $this->post('chunk'), 'state' => $state, 'updateTime' => $this->time],
                    "where" => " id = '" . $info['id'] . "' "
                ]);
                if ($json['warn'] == '更新成功') {
                    $json['warn']     = 2;
                    $json['state']    = $state;
                    $json['progress'] = $progress;
                    if ($state == 1) $_SESSION['warn'] = '上传成功';
                }
                goto resp;
            }
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 文件上传中止
     */
    public function uploadAborted()
    {
        $id              = $this->post('id');
        $where           = " id = '" . $id . "' ";
        $upload_progress = query("upload_progress", $where);
        if (empty($upload_progress['id'])) {
            $json['warn'] = '未找到上传记录';
        } else {
            // 删除表
            delete([
                "table" => 'upload_progress',
                "where" => $where
            ]);
            for ($i = 1; $i <= $upload_progress['chunks']; $i++) {
                $chunkName = serverRoot . 'file/temp/' . $upload_progress['id'] . "_" . $i;
                @unlink($chunkName); //删除分片文件
            }
            $json['warn'] = 2;
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * 保存上传的文件到服务器，临时文件夹
     *
     * @param array $file 文件数组
     * @param string $saveDir 保存文件夹名称
     * @param float $maxSize 上传最大文件限制
     * @param string $fileName 指定文件名称
     * @return array 返回保存路径和警告信息  code:1 成功 0 失败
     */
    public function saveFileTemp(array $file, string $fileName, string $saveDir = 'temp', float $maxSize = 0): array
    {
        $maxSize  = empty($maxSize) ? 1024 * 1024 * 6 : $maxSize;
        $tmp_name = $file['tmp_name'];
        $size     = 0;
        $src      = '';
        if ($file['error'] != UPLOAD_ERR_OK) {
            $warn = $this->getFileErrorInfo($file['error']);
        } elseif ($file['size'] > $maxSize) {
            $warn = '上传文件大于最大上传大小(M)' . ($maxSize / 1024 / 1024);
        } elseif (empty($saveDir)) {
            $warn = '缺少保存文件夹名称';
        } else {
            $id  = $fileName;
            $url = 'file/' . $saveDir;
            $this->_mkdir($url);
            $src  = $url . "/" . $id; //保存附件的根目录路径
            $size = filesize($tmp_name);              //文件体积
            if (move_uploaded_file($tmp_name, serverRoot . $src)) {
                $warn = '上传成功';
            } else {
                $warn = '上传失败';
            }
        }
        return array('code' => $warn == '上传成功' ? 1 : 0, 'warn' => $warn, 'size' => $size, 'src' => $src);
    }

    public static function getNavArr($pid)
    {
        $temp = $pid . ',';
        $info = query(self::table, " id = '$pid' AND `type` = 'folder' ");
        if ($info['id']) {
            $temp .= $info['pid'] . ',';
            if ($info['pid']) {
                $temp .= self::getNavArr($info['pid']);
            }
        }
        return $temp;
    }

    /**
     * 获取导航条
     *
     * @return string
     */
    public static function getNavHtml($pid): string
    {
        $pidStr = self::getNavArr($pid);
        $temp   = explode(',', trim($pidStr));
        // 倒序
        $temp = array_reverse($temp);
        // 去重
        $array  = array_unique($temp);
        $string = '';
        $href   = "<a class='spanA' onclick=\"refreshNowIframe('" . root . "control/adIndex.html?cla=share&fun=home&pid={{pid}}');\">{{name}}</a>";
        foreach ($array as $pid) {
            if ($pid == 1) {
                $string .= str_replace(['{{pid}}', '{{name}}'], ['1', '文件共享'], $href);
            } else {
                $info = query(self::table, " id = '$pid' ");
                if ($info['id']) {
                    $string .= ' > ' . str_replace(['{{pid}}', '{{name}}'], [$info['id'], $info['name']], $href);
                }
            }
        }
        return $string;
    }


    /**
     * Desc : 显示上传控件
     * User : you name
     * Date : 2024-02-22 11:45
     * @param $pid
     * @param $fileId
     * @param $url
     * @return string
     */
    public function uploadHtml($pid, $fileId, $url)
    {
        $formName = $fileId . 'form';
        return '
            <div class="hide">
                <form name="' . $formName . '" method="post" action="' . root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=upload" enctype="multipart/form-data">
                    <input name="img" type="file" multiple onchange="choiceFileUpload(this, \'' . $pid . '\', \'' . $url . '\')">
                    <input name="pid" type="hidden" value="' . $pid . '">
                </form>
            </div>' .
            "<script>
                function choiceFileUpload(e, pid, url) {
                    var fileList = $(e).prop('files'); //获取文件对象
                    var arr = [];
                    const chunkSize = 5 * 1024 * 1024;
                    $.each(fileList,function(n,file){
                        var value = {
                            'code':  CryptoJS.MD5(file.name + file.size + file.lastModified).toString(),
                            'target':  '1',
                            'name':  file.name,
                            'size':  file.size,
                            'target_id':  pid,
                            'chunks':  Math.ceil(file.size / chunkSize),
                            'power':  'share',
                            'error':  '',
                        }
                        arr.push(value)
                    });
                    $.post(root + 'control/adIndex.html?cla=share&fun=checkUpload', {fileInfo:JSON.stringify(arr)}, function (res) {
                        if(res.warn === 2){
                            layer('share', 'uploadList', {'fileInfo': res.data, 'notClose': 1  })
                            //分片上传
                            for (var i = 0; i < res.data.length; i++) {
                                uploadChunks(fileList[i], res.data[i], url)
                            }
                        }else{
                            msg(res.warn, 'error')
                        }
                    }, 'json')
                }
            </script>";
    }

    // 图片上传
    public function upload()
    {
        $id    = self::getNo();
        $pid   = $this->post('pid') ?? 1;
        $field = [];
        if (!$this->power(self::page, 'edit')) {
            $warn = "你还没有上传的权限";
        } else {
            $pInfo  = query(self::table, " id = '$pid' ");
            $result = $this->saveFile($_FILES['img'], self::table, explode(',', para('fileFormat')));
            if ($result['code']) {
                $field['path']      = $result['src'];
                $field['name']      = $result['fileName'];
                $field['size']      = $result['size'];
                $field['viewScope'] = $pInfo['viewScope'];
                $field              = array_merge($field, [
                    'id'     => $id,
                    'pid'    => $pid,
                    'type'   => 'file',
                    'stid'   => self::$stid,
                    'suffix' => $result['suffix'],
                    'time'   => date("Y-m-d H:i:s"),
                ]);
                $warn               = insert([
                    'table' => self::table,
                    'field' => $field
                ]);
                if ($warn == "新增成功") {
                    $warn = "上传成功";
                    //添加日志
                    $text = $this->control['name'] . "上传了了一个共享文件，文件名：【{$field['name']}】, ID【{$id}】";
                    $this->logText(["type" => self::page, "text" => $text]);
                }
            }
        }
        $_SESSION['warn'] = $warn;
        $locationUrl      = root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home&pid=' . $pid;
        header("location:" . $locationUrl);
        exit(0);
    }

    /**
     * Desc : 拖拽上传
     * User : you name
     * Date : 2024-02-21 09:38
     * @param $pid
     * @param $url
     * @param $node
     * @return string
     */
    public function dragUploadHtml($pid, $url, $node)
    {
        return "
    <div id='windowMaskView' class='maskView'></div>
    <div id='maskViewContent' class='viewContent'>
        <div class='content-div'>
            <div class='upload-tips'>						
                <div class='cloud-icon'>							
                    <i class='icon-cloud cloud1 moveLeftLoop'></i>
                    <i class='icon-cloud cloud2'></i>
                    <i class='icon-cloud cloud3 moveLeftLoop'></i>
                </div>
                <div class='cloud-moveup'>
                    <i class='moveTopLoop icon-circle-arrow-up'></i>
                </div>						
                <div class='msg'>松开即可上传!</div>
            </div>
        </div>
    </div>
    <script>
        var pid = '{$pid}'
        var url = '{$url}'
        var node = '{$node}'
        $(document).ready(function(){
            let elemetnNode=''//最后一次节点
            //要想实现拖拽，首页需要阻止浏览器默认行为，一个四个事件。
            $('#'+node).on({
                dragleave:function(e){		//拖离
                    e.preventDefault();     //移除原有浏览器监听效果
                    if(elemetnNode===e.target)
                    $('.maskView,.viewContent').removeClass('over');
                },
                drop:function(e){			//拖后放
                    e.preventDefault();     //移除原有浏览器监听效果
                },
                dragenter:function(e){		//拖进
                    elemetnNode=e.target;
                    e.preventDefault();     //移除原有浏览器监听效果
                    $('.maskView,.viewContent').addClass('over');
                },
                dragover:function(e){		//拖来拖去
                    e.preventDefault();     //移除原有浏览器监听效果
                    $('.maskView,.viewContent').addClass('over');
                }
            });
            
            //================上传的实现
            var box = document.getElementById(node); //获得到框体
            var newHandle = function(e){
                e.preventDefault(); //取消默认浏览器拖拽效果
                e.stopPropagation()
                var fileList = e.dataTransfer.files; //获取文件对象
                //fileList.length 用来获取文件的长度（其实是获得文件数量）
                console.log(fileList)
                
                //检测是否是拖拽文件到页面的操作
                if(fileList.length == 0){
                    $('.maskView,.viewContent').removeClass('over');
                    return;
                }
                var arr = [];
                const chunkSize = 5 * 1024 * 1024;
                $.each(fileList,function(n,file){
                    var value = {
                        'code':  CryptoJS.MD5(file.name + file.size + file.lastModified).toString(),
                        'target':  '1',
                        'name':  file.name,
                        'size':  file.size,
                        'target_id':  pid,
                        'chunks':  Math.ceil(file.size / chunkSize),
                        'power':  'share',
                        'error':  '',
                    }
                    arr.push(value)
                });
                $.post(root + 'control/adIndex.html?cla=share&fun=checkUpload', {fileInfo:JSON.stringify(arr)}, function (res) {
                    $('.maskView,.viewContent').removeClass('over');
                    if(res.warn === 2){
                        layer('share', 'uploadList', {'fileInfo': res.data, 'notClose': 1 })
                        //分片上传
                        for (var i = 0; i < res.data.length; i++) {
                            uploadChunks(fileList[i], res.data[i], url)
                        }
                        box.removeEventListener(\"drop\",newHandle);
                    }else{
                        msg(res.warn, 'error')
                    }
                }, 'json')
            }
            box.addEventListener(\"drop\",newHandle,false);
        });
            
    </script>";
    }

    public function editPage()
    {
        $info = query(self::table, " id = '" . $this->post('id') . "' ");
        // 员工选择
        /*$staffOption = [];
        $all        = $this->sqlFind("SELECT `stid`,`name` FROM `staff` WHERE 1=1 ORDER BY name ASC ");
        foreach ($all as $val) {
            $staffOption[$val['stid']] = $val['name'];
        }
        // 查看范围
        $viewScopeArr = (array) json_decode($info['viewScope'], true);
        $viewScope = implode(',', $viewScopeArr);*/

        $html = $this->layerEdit([
            "table" => [
                [
                    must . "文件夹名称" => text(['name' => 'name', 'value' => $info['name'], 'class' => 'text']),
                ],
                [
                    must . '查看范围' => componentClass::staffSelector($info['viewSelector'], name: 'viewSelector'),
                ],
                [
                    must . '可删除人员' => componentClass::staffSelector($info['delSelector'], name: 'delSelector'),
                ],
                [
                    "备注" => textarea(['name' => 'text', 'value' => $info['text'], 'class' => 'text']) . hidden(['name' => 'pid', 'value' => $info['pid'] ? $info['pid'] : $this->post('pid')]),
                ]
            ]
        ]);
        return $this->layer(array("title" => "编辑" . self::title, "height" => 400, "width" => 900, "html" => $html));
    }

    /*成本表基本资料新增或修改-异步处理*/
    public function editPageEdit()
    {
        $id                 = $this->post('id') ?? self::getNo();
        $field              = [
            'pid'          => $this->post('pid') ?? 1,
            'type'         => 'folder',
            'name'         => $this->post('name'),
            'viewSelector' => $this->post('viewSelector')[0] ?? '',//查看范围员工选择器
            'delSelector'  => $this->post('delSelector')[0] ?? '',//可删除人员员工选择器
            'text'         => $this->post('text'),
        ];
        $field['viewScope'] = json_encode(componentClass::returnStaffId($field['viewSelector']), 320);
        $field['delScope']  = json_encode(componentClass::returnStaffId($field['delSelector']), 320);
        $annotation         = [
            'pid'          => '上级ID',
            'type'         => '类型',
            'name'         => '文件名',
            'viewSelector' => '查看范围',
            'delSelector'  => '可删除人员',
            'text'         => '备注',
        ];
        $rules              = [
            'pid'       => 'required|unsigned_int',
            'type'      => 'required',
            'name'      => 'required',
            'viewScope' => 'required',
            'delScope'  => 'required',
            // 'text'      => 'required',
        ];
        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0]; // 多个规则提示最前面一条
            goto resp;
        }
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有编辑" . self::title . "的权限";
        } else {
            $where = " id = '$id' ";
            $info  = query(self::table, $where);
            if (sqlNum(self::table, " pid = '{$field['pid']}' AND name = '{$field['name']}' AND id <> '$id'   ") > 0) {
                $json['warn'] = "当前层级下已存在该目录【{$field['name']}】";
                goto resp;
            }

            if (!$info['id']) {
                $field        = array_merge($field, [
                    'id'   => $id,
                    'stid' => self::$stid,
                    'time' => $this->time
                ]);
                $json['warn'] = static::insert(["table" => self::table, "field" => $field,]);
            } else {
                $json['warn'] = static::update([
                    "table" => self::table,
                    "field" => $field,
                    "where" => $where
                ]);
            }
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home&pid=" . $field['pid'];
            }
        }

        resp:
        return json_encode($json, 320);
    }

    public static function getLevelAll($data = [])
    {
        // 条件
        $data['where'] = isset($data['where']) ? $data['where'] : "pid='1' AND (`viewScope` like '%" . self::$stid . "%' OR `stid` = '" . self::$stid . "')";
        // 点击事件
        $data['click'] = isset($data['click']) ? $data['click'] : 'selection(this, \'pid\')';
        // 结果
        $result = find(['table' => self::table, 'where' => $data['where'] . " AND `type` = 'folder' "]);
        $style  = ($data['where'] == "pid='1' AND (`viewScope` like '%" . self::$stid . "%' OR `stid` = '" . self::$stid . "')") ? '' : ' class="child-node"';
        $temp   = "<ul {$style} {$data['where']}>";
        // 角标
        $arrow = "<span class='arrow' onclick=\"liZoom($(this).parent())\"></span>";
        $lastone = lastone;
        $textcontent_ico = "<span class='textcontent_ico'></span>";
        if(empty($style)) {
            $temp .= "<li data-id='1' onclick=\"selection(this, 'pid')\">$arrow <span class='textcontent'>{$textcontent_ico}根目录</span></li>";
            $temp   .= "<ul  class='child-node' pid='1' AND (`viewScope` like '%" . self::$stid . "%' OR `stid` = '" . self::$stid . "')>";
        }
        if ($result['array']) {
            foreach ($result['array'] as $value) {
                // 判断下级是否存在
                $data['where'] = " pid='{$value['id']}' AND `type` = 'folder' AND (`viewScope` like '%" . self::$stid . "%' OR `stid` = '" . self::$stid . "')";
                $has           = query(self::table, $data['where']);
                if ($has) {
                    $temp .= "<li data-id='{$value['id']}' onclick=\"{$data['click']}\">$arrow <span class='textcontent'>{$textcontent_ico}{$value['name']}</span></li>";
                    $temp .= self::getLevelAll($data);
                } else {
                    $temp .= "<li data-id='{$value['id']}' onclick=\"{$data['click']}\">$lastone <span class='textcontent'>{$textcontent_ico}{$value['name']}</span></li>";
                }
            }
        }
        $temp .= '</ul>';
        return $temp;
    }

    /**
     * 移动文件夹 下拉
     *
     * @return string
     */
    public function moveHtml(): string
    {
        $search          = "<div class='container-left-search-parent flex-box'>
                                ".text(["name" => 'name', 'title' => "搜索文件夹", 'class' => 'container-left-search', 'other' => " onkeyup='search_left(this,event)' "])."
                                <i class='container-left-search-ico' onclick=\"search_left(document.getElementsByClassName('container-left-search')[0])\"></i>
                                <span class='search-count'></span>
                            </div>";
        $all = self::getLevelAll();
        return <<<efo
                    <div class="layer-container-main">
                        <div class="container-left" id="container-left">
                          {$search}
                           <div class="classify-area">
                                $all
                            </div>
                        </div>
                    </div>
<script>
$(document).ready(function(){
    //初始化左侧分类标记和定位
    search_left(document.getElementsByClassName('container-left-search')[0])
});
</script>
<style>
.layer-container-main .container-left{height: 235px;flex: 1;}
.layer-container-main .container-left .classify-area {height: 183px;overflow: auto;}
</style>
efo;
    }

    // 操作中转
    public function operate()
    {
        $act    = $this->post('act') ?? '';
        $pwd    = $height = $width = $zindex = false; // 需要密码、 指定高度
        $form   = $power = '';
        $append = [];
        switch ($act) {
            case 'range':
            case 'changeState':
                $act         = 'edit';
                $msg         = self::title . '修改状态';
                $title       = '';
                $function    = 'changeState';
                $form        = self::page . 'OperateForm, listForm';
                $staffOption = [];
                $all         = $this->sqlFind("SELECT `stid`,`name` FROM `staff` WHERE 1=1  ORDER BY name ASC ");
                foreach ($all as $val) {
                    $staffOption[$val['stid']] = $val['name'];
                }
                $info   = query(self::table, " id = '{$this->post('id')}' ");
                $append = [
                    [must . '查看范围' => componentClass::staffSelector($info['viewSelector'], name: 'viewSelector') . space],
                    [must . '可删除人员' => componentClass::staffSelector($info['delSelector'], name: 'delSelector') . space],
                    [must . '可下载人员' => componentClass::staffSelector($info['downloadSelector'], name: 'downloadSelector') . space],
                ];
                $height = 540;
                $width  = 885;
                $zindex = 2;
                break;
            // 移动
            case 'move':
                $act      = 'edit';
                $msg      = self::title . '修改状态';
                $title    = '';
                $function = 'moveData';
                $form     = self::page . 'OperateForm, listForm';
                $append   = [
                    $this->moveHtml().hidden(['name' => 'pid', 'id' => 'pid']),
                ];
                $height   = 340;
                break;
            // 压缩
            case 'zip':
                $act      = 'zip';
                $msg      = self::title . '压缩';
                $title    = '';
                $function = 'batchZip';
                $form     = self::page . 'OperateForm, listForm';
                $info     = query(self::table, " id = '{$this->post('pid')}' ");
                $filename = $info['name'] . date("YmdHis"); //下载的默认文件名
                $append   = [
                    must . "压缩文件名称:" => text(['name' => 'filename', 'value' => $filename, 'class' => 'text width300']),
                    0                => '<span>.zip</span>' . hidden(['name' => 'pid', 'value' => $this->post('pid')])
                ];
                $height   = 176;
                break;
            default:
                $act      = 'del';
                $msg      = '删除' . self::title;
                $title    = self::table . 'Delete';
                $function = 'isDelete';
                $form     = 'shareOperateForm, listForm';
                $power    = '';
                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = '你还没有' . $msg . '的权限';
            $json             = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title'    => $title,
                'function' => $function,
                'form'     => $form,
                'power'    => $power,
                'pwd'      => $pwd,
                'append'   => $append,
                'height'   => $height,
                'width'    => $width,
                'zindex'   => $zindex,
            ]);
        }

        resp:
        return json_encode($json, 320);
    }

    // 批量压缩
    public function batchZip()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "zip")) {
            $json['warn'] = "你没有压缩" . self::title . "的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一条记录都没有选择呢";
        } else {
            $dir       = query("share", " id = '" . $this->post('pid') . "' ");
            $dir['id'] = $dir['id'] ?: 1;

            $and   = "";
            $alias = "";
            if (!$this->power(self::page, "zip")) {
                $and .= "  and ({$alias}`downloadScope` like '%" . self::$stid . "%' OR {$alias}`delScope` like '%" . self::$stid . "%' OR {$alias}`viewScope` like '%" . self::$stid . "%' OR {$alias}`stid` = '" . self::$stid . "' OR type = 'folder') ";
            }
            $result = find(['table' => self::table, 'where' => " id in ('" . implode("','", $array) . "') " . $and]);
            $files  = [];
            foreach ((array)$result['array'] as $val) {
                if ($val['type'] == 'folder') {
                    $files = array_merge($files, $this->getFileAll(['where' => " pid = '" . $val['id'] . "' ", 'attach_where' => $and], $val['name'] . '/'));
                } else {
                    $files[] = array("file" => serverRoot . $val['path'], "name" => $val['name']);
                }
            }
            $res = $this->fileZip($files, 'share', $this->post('filename'));
            if ($res !== false) {
                $field['path']             = $res['path'];
                $field['name']             = $res['filename'];
                $field['size']             = $res['size'];
                $field['viewScope']        = $dir['viewScope'];
                $field['viewSelector']     = $dir['viewSelector'];
                $field['delScope']         = $dir['delScope'];
                $field['delSelector']      = $dir['delSelector'];
                $field['downloadScope']    = $dir['downloadScope'];
                $field['downloadSelector'] = $dir['downloadSelector'];
                $id                        = self::getNo();
                $field                     = array_merge($field, [
                    'id'     => $id,
                    'pid'    => $dir['id'],
                    'type'   => 'file',
                    'stid'   => self::$stid,
                    'suffix' => $res['suffix'],
                    'time'   => date("Y-m-d H:i:s"),
                ]);
                $warn                      = insert([
                    'table' => self::table,
                    'field' => $field
                ]);
                if ($warn == "新增成功") {
                    // 写入日志
                    $text = $this->control['name'] . "创建了压缩文件【{$res['filename']}】";
                    $this->logText(["type" => self::page, "text" => $text]);
                    $_SESSION['warn'] = "压缩成功";
                    $json['warn']     = 2;
                    $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home&pid=" . $dir['id'];
                }
            }
        }
        resp:
        return json_encode($json, 320);
    }


    // 确认删除信息
    public function isDelete()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = "你没有删除" . self::title . "的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一条记录都没有选择呢";
        } else {
            $text  = '';
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $where = " id = '$id' ";
                $info  = query(self::table, $where);
                //删除权限判断
                $delScope = $info['delScope'] ? json_decode($info['delScope'], true) : [];
                if (!in_array(self::$stid, (array)$delScope) && self::$stid != $info['stid']) {
                    $text .= "管理员{$this->control['name']}删除" . self::title . "：ID【{$id}】失败，没有删除权限<br>";
                } elseif ($info['id']) {
                    // 删除表
                    delete([
                        "table" => self::table,
                        "where" => $where
                    ]);
                    fileDelete($info['path']);
                    //添加记录
                    $text .= "管理员{$this->control['name']}删除了一个" . self::title . "：ID【{$id}】<br>";
                    $x++;
                }
            }
            // 写入日志
            $this->logText(["type" => self::page, "text" => $text]);
            $_SESSION['warn'] = "删除了{$x}条" . self::title;
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home&pid=" . $info['pid'];
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * Desc : 移动函数
     * User : you name
     * Date : 2024-02-21 09:39
     * @return false|string
     */
    public function moveData()
    {
        $array = $this->post('listId') ?? $this->post('id');
        $pid   = $this->post('pid');
        $act   = 'edit';
        $json  = [];
        if (!$this->power(self::page, $act)) {
            $json['warn'] = "你没有此权限的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一条记录都没有选择呢";
        } elseif (empty($pid)) {
            $json['warn'] = "请选择你要移动的文件夹";
        } else {
            $text  = '';
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            // 修改field
            foreach ($array as $id) {
                $where = " id = '$id' ";
                $info  = query(self::table, $where);
                if ($info['stid'] != self::$stid) {
                    $text .= "{$this->control['name']}非文件：ID【{$id}】" . (!static::isNull($info['name']) ? "，文件名【{$info['name']}】" : '') . '创建者，无法移动<br>';
                    continue;
                }
                if ($info['id'] && $info['pid'] != $pid) {
                    // 修改状态
                    static::update([
                        "table" => self::table,
                        'field' => [
                            'pid' => $pid,
                        ],
                        "where" => $where
                    ]);
                    //添加记录
                    $text .= "{$this->control['name']}移动了文件：ID【{$id}】" . (!static::isNull($info['name']) ? "，文件名【{$info['name']}】" : '') . '<br>';
                    $x++;
                }
            }
            // 写入日志
            $this->logText(["type" => self::page, "text" => $text]);
            $_SESSION['warn'] = "移动了{$x}个文件（夹）";
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home&pid=" . $info['pid'];
        }
        resp:
        return json_encode($json, 320);
    }

    /**
     * Desc : 修改状态
     * User : you name
     * Date : 2024-02-21 09:39
     * @return false|string
     */
    public function changeState()
    {
        $array = $this->post('listId') ?? $this->post('id');
        $act   = 'edit';
        $json  = [];
        if (!$this->power(self::page, $act)) {
            $json['warn'] = "你没有此权限的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一条记录都没有选择呢";
        } else {
            $text  = '';
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            // 修改field
            foreach ($array as $id) {
                $where = " id = '$id' ";
                $info  = query(self::table, $where);
                if ($info['id']) {
                    $viewScope     = $this->post('viewSelector')[0] ? json_encode(componentClass::returnStaffId($this->post('viewSelector')[0]), 320) : '';
                    $delScope      = $this->post('delSelector')[0] ? json_encode(componentClass::returnStaffId($this->post('delSelector')[0]), 320) : '';
                    $downloadScope = $this->post('downloadSelector')[0] ? json_encode(componentClass::returnStaffId($this->post('downloadSelector')[0]), 320) : '';
                    // 修改状态
                    static::update([
                        "table" => self::table,
                        'field' => [
                            'viewScope'        => $viewScope,
                            'viewSelector'     => $this->post('viewSelector')[0] ?? '',//查看范围员工选择器
                            'delScope'         => $delScope,
                            'delSelector'      => $this->post('delSelector')[0] ?? '',//可删除人员员工选择器
                            'downloadScope'    => $downloadScope,
                            'downloadSelector' => $this->post('downloadSelector')[0] ?? '',//可下载人员员工选择器
                        ],
                        "where" => $where
                    ]);
                    //添加记录
                    $text .= "{$this->control['name']}修改文件共享权限" . self::title . "：ID【{$id}】" . ($info['name'] ? "，文件名【{$info['name']}】" : '') . '<br>';
                    $x++;
                }
            }
            // 写入日志
            $this->logText(["type" => self::page, "text" => $text]);
            $_SESSION['warn'] = "修改了{$x}个" . self::title;
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home&pid=" . $info['pid'];
        }
        resp:
        return json_encode($json, 320);
    }
}
